﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using rpxnow_library.rpxnowapi.conf;

namespace rpxnow_library.rpxnowapi
{
    static internal class Pipeline
    {
        /// <summary>
        /// Posts the api call and returns the raw string returned.
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="partialQuery"></param>
        /// <param name="responseDataFormat"></param>
        /// <returns></returns>
        static public string ApiCall(string methodName, IDictionary<string, string> partialQuery, string responseDataFormat)
        {
            string requestData = Pipeline.BuildRequestData(partialQuery, responseDataFormat);

            Uri requestUrl = new Uri(ApplicationConfiguration.RootUrl + methodName);

            HttpWebResponse response = Pipeline.PostRequest(requestData, requestUrl);

            return Pipeline.ExtractResponseData(response);
        }

        private static string ExtractResponseData(HttpWebResponse response)
        {
            using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
            {
                return responseStream.ReadToEnd();
            }
        }

        private static HttpWebResponse PostRequest(string data, Uri url)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = data.Length;

            using (StreamWriter requestStream = new StreamWriter(request.GetRequestStream(), Encoding.ASCII))
            {
                requestStream.Write(data);
            }

            return (HttpWebResponse)request.GetResponse();
        }

        private static string BuildRequestData(IDictionary<string, string> partialQuery, string format)
        {
            var query = Pipeline.CompileCompleteQuery(partialQuery, format);
            return Pipeline.BuildDataString(query);
        }

        private static string BuildDataString(IDictionary<string, string> query)
        {
            StringBuilder sb = new StringBuilder();
            foreach (KeyValuePair<string, string> e in query)
            {
                if (sb.Length > 0)
                {
                    sb.Append('&');
                }

                sb.Append(HttpUtility.UrlEncode(e.Key, Encoding.UTF8));
                sb.Append('=');
                sb.Append(HttpUtility.UrlEncode(e.Value, Encoding.UTF8));
            }
            return sb.ToString(); ;
        }

        private static IDictionary<string, string> CompileCompleteQuery(IDictionary<string, string> partialQuery, string format)
        {
            Dictionary<string, string> query = new Dictionary<string, string>(partialQuery);
            query.Add("format", format);
            query.Add("apiKey", ApplicationConfiguration.ApiKey);
            return query;
        }
    }
}
